package deconstruction.deconTable;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;

import com.google.common.collect.Lists;

import net.minecraft.block.Block;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
import net.minecraft.item.ItemEnchantedBook;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.ShapedRecipes;
import net.minecraft.item.crafting.ShapelessRecipes;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.World;

public class DeconstructionManager
{
	/** The static instance of this class */
	private static final DeconstructionManager instance = new DeconstructionManager();

	public int itemStackSize = 1;

	public int getItemStackSize() {
		return itemStackSize;
	}

	public void setItemStackSize(int itemStackSize) {
		this.itemStackSize = itemStackSize;
	}

	/** A list of all the recipes added */
	private List allRecipes = new ArrayList();
	private List recipes = new ArrayList();

	/**
	 * Returns the static instance of this class
	 */
	public static final DeconstructionManager getInstance()
	{
		return instance;
	}

	public void addShapedRecipe(ShapedRecipes shapedrecipes){
		this.allRecipes.add(shapedrecipes);
	}
	public void addShapelessRecipe(ShapelessRecipes shapelessRecipes){
		this.allRecipes.add(shapelessRecipes);
	}
	
    public ShapedRecipes addRecipe(ItemStack par1ItemStack, Object ... par2ArrayOfObj)
    {
    	try{
        String s = "";
        int i = 0;
        int j = 0;
        int k = 0;

        if (par2ArrayOfObj[i] instanceof String[])
        {
            String[] astring = (String[])((String[])par2ArrayOfObj[i++]);

            for (int l = 0; l < astring.length; ++l)
            {
                String s1 = astring[l];
                ++k;
                j = s1.length();
                s = s + s1;
            }
        }
        else
        {
            while (par2ArrayOfObj[i] instanceof String)
            {
                String s2 = (String)par2ArrayOfObj[i++];
                ++k;
                j = s2.length();
                s = s + s2;
            }
        }

        HashMap hashmap;

        for (hashmap = new HashMap(); i < par2ArrayOfObj.length; i += 2)
        {
            Character character = (Character)par2ArrayOfObj[i];
            ItemStack itemstack1 = null;

            if (par2ArrayOfObj[i + 1] instanceof Item)
            {
                itemstack1 = new ItemStack((Item)par2ArrayOfObj[i + 1]);
            }
            else if (par2ArrayOfObj[i + 1] instanceof Block)
            {
                itemstack1 = new ItemStack((Block)par2ArrayOfObj[i + 1], 1, 32767);
            }
            else if (par2ArrayOfObj[i + 1] instanceof ItemStack)
            {
                itemstack1 = (ItemStack)par2ArrayOfObj[i + 1];
            }

            hashmap.put(character, itemstack1);
        }

        ItemStack[] aitemstack = new ItemStack[j * k];

        for (int i1 = 0; i1 < j * k; ++i1)
        {
            char c0 = s.charAt(i1);

            if (hashmap.containsKey(Character.valueOf(c0)))
            {
                aitemstack[i1] = ((ItemStack)hashmap.get(Character.valueOf(c0))).copy();
            }
            else
            {
                aitemstack[i1] = null;
            }
        }

        ShapedRecipes shapedrecipes = new ShapedRecipes(j, k, aitemstack, par1ItemStack);
        this.allRecipes.add(shapedrecipes);
        return shapedrecipes;
    	}catch(Exception e){
    		return null;
    	}
    }

    public void addShapelessRecipe(ItemStack par1ItemStack, Object ... par2ArrayOfObj)
    {
    	try{
        ArrayList arraylist = new ArrayList();
        Object[] aobject = par2ArrayOfObj;
        int i = par2ArrayOfObj.length;

        for (int j = 0; j < i; ++j)
        {
            Object object1 = aobject[j];

            if (object1 instanceof ItemStack)
            {
                arraylist.add(((ItemStack)object1).copy());
            }
            else if (object1 instanceof Item)
            {
                arraylist.add(new ItemStack((Item)object1));
            }
            else
            {
                if (!(object1 instanceof Block))
                {
                    throw new RuntimeException("Invalid shapeless recipy!");
                }

                arraylist.add(new ItemStack((Block)object1));
            }
        }

        this.allRecipes.add(new ShapelessRecipes(par1ItemStack, arraylist));
    	}catch(Exception e){
    	}
    }
    
    
    
    
    

	public ItemStack[] findSingleRecipe(ItemStack in, int recipeNumber)
	{
		List list = DeconstructionManager.getInstance().getRecipeList(in);
		ItemStack[] stacks = new ItemStack[9];
		ItemStack[] items = new ItemStack[0];
		ItemStack stack1;
		try{
			if (!list.isEmpty() && list.size()-1 >= recipeNumber)
			{

				if(list.get(recipeNumber) instanceof ShapedRecipes)
				{
					this.setItemStackSize(((ShapedRecipes) list.get(recipeNumber)).getRecipeOutput().stackSize);
					items = ((ShapedRecipes) list.get(recipeNumber)).recipeItems;
				}

				if(list.get(recipeNumber) instanceof ShapelessRecipes)
				{	
					this.setItemStackSize(((ShapelessRecipes) list.get(recipeNumber)).getRecipeOutput().stackSize);
					ArrayList<ItemStack> finalItems = new ArrayList<ItemStack>();
					ArrayList arraylist = new ArrayList(((ShapelessRecipes) list.get(recipeNumber)).recipeItems);
					Iterator iterator = arraylist.iterator();	
					items = new ItemStack[((ShapelessRecipes) list.get(recipeNumber)).recipeItems.size()];
					int i = -1;
					while (iterator.hasNext())
					{
						i++;
						ItemStack itemstack1 = (ItemStack)iterator.next();
						items[i] = itemstack1;
					}
				}	


				for(int i = 0; i<items.length; i++){
					if(items[i] != null && ((ItemStack) ((IRecipe)list.get(recipeNumber)).getRecipeOutput()).stackSize <= in.stackSize){
						stacks[i] = new ItemStack(items[i].itemID, 1, items[i].getItemDamage() == 32767 ? 32767 :items[i].getItemDamage());
					}else{
						stacks[i] = null;
					}
				}

				ItemStack inStack = in.copy();
				if(inStack.isItemDamaged()){
					int damage = inStack.getItemDamage();
					int maxDamage = inStack.getMaxDamage();
					Double percentDamaged = Math.ceil((damage*100)/maxDamage);
					List slotsUsed = new ArrayList();

					for(int i = 0; i<stacks.length; i++){
						if(stacks[i] != null)
							slotsUsed.add(stacks[i]);
					}

					int itemCount = slotsUsed.size();

					if(itemCount != 0){
						int damagePerItem = (int)Math.ceil(100/itemCount);
						int l = -1;
						for(int k= 0; k<=percentDamaged; k= k+damagePerItem){
							l++;
							stacks[l] = null;      
						}
					}
					slotsUsed.clear();
				}



				if(containsItem(items, Arrays.asList(Item.bucketMilk.itemID, Item.dyePowder.itemID, Item.bucketWater.itemID, Item.bucketLava.itemID))){
					for(int i = 0; i<9; i++){
						stacks[i] = null;
					}
				}



			}

			return stacks;
		}catch(Exception e){
			//System.out.println(e.getMessage());
			//e.printStackTrace();
		}

		return stacks;

	}
	public ItemStack undoEnchant(ItemStack stack){
		Map enchantMap = EnchantmentHelper.getEnchantments(stack);
		int enchantQty = enchantMap.size();
		Random rand = new Random();
		int enchantNum = 0;

		if(enchantQty<2){
			enchantNum = 0;
		}else{
			enchantNum = rand.nextInt(enchantQty-1);
		}

		ItemStack newStack = new ItemStack(Item.enchantedBook, 1);
		Map theEnchant = new HashMap();
		theEnchant.put(enchantMap.keySet().toArray()[enchantNum], enchantMap.get(enchantMap.keySet().toArray()[enchantNum]));
		EnchantmentHelper.setEnchantments(theEnchant, newStack);
		return newStack;
	}

	public List getRecipeList(ItemStack stack){
		try{
			List addedRecipes = new ArrayList();
			for(int i = 0; i < allRecipes.size(); ++i){
				IRecipe recipe = (IRecipe)this.allRecipes.get(i);
				ItemStack[] items = null;
				if(stack != null)

					if(this.allRecipes.get(i) instanceof ShapedRecipes)
					{
						items = ((ShapedRecipes) this.allRecipes.get(i)).recipeItems;
					}

				if(this.allRecipes.get(i) instanceof ShapelessRecipes)
				{	
					ArrayList<ItemStack> finalItems = new ArrayList<ItemStack>();
					ArrayList arraylist = new ArrayList(((ShapelessRecipes) this.allRecipes.get(i)).recipeItems);
					Iterator iterator = arraylist.iterator();	
					items = new ItemStack[((ShapelessRecipes) this.allRecipes.get(i)).recipeItems.size()];
					int j = -1;
					while (iterator.hasNext())
					{
						j++;
						ItemStack itemstack1 = null;
						try{
							itemstack1 = (ItemStack) iterator.next();
							items[j] = itemstack1;
						}catch(Exception e){
							e.printStackTrace();
						}
					}
				}	

				List<Integer> ints = new ArrayList();
				ints = Arrays.asList(3, 4);
				int damage = 0;
				if(stack != null){
					if(stack.getItemDamage() == 32767){
						damage = 0;
					}else{
						damage = stack.getItemDamage();
					}
					if(stack.isItemDamaged()){
						damage = recipe.getRecipeOutput().getItemDamage();
					}
				


				if(recipe.getRecipeOutput().itemID == stack.itemID && recipe.getRecipeOutput().getItemDamage() == damage && !Arrays.asList().contains(stack.itemID) && !(containsItem(items, Arrays.asList(
						Item.bucketMilk.itemID, Item.dyePowder.itemID
						)))){
					addedRecipes.add(recipe);
				}
				}
			}
			return addedRecipes;
		}catch(Exception e){e.printStackTrace();}
		return null;

	}

	public boolean containsItem(ItemStack[] array, List idList){
		if(array!=null){
			List<ItemStack> list = Arrays.asList(array);
			Iterator iterator = list.iterator();
			while(iterator.hasNext()){
				ItemStack stack = (ItemStack) iterator.next();
				if(stack != null){
					if(idList.contains(stack.itemID)){
						return true;
					}
				}
			}
		}

		return false;
	}

	public List getCompleteRecipeList()
	{
		return this.allRecipes;
	}
	/*
	public int checkList() {
		int recipesAdded = 0;
		List completeList = CraftingManager.getInstance().getRecipeList();
		if(completeList != null){
			Iterator iterator = completeList.iterator();
			while(iterator.hasNext()){
				Object o = iterator.next();
				if(!this.allRecipes.contains(o)){
					this.allRecipes.add(o);
					recipesAdded++;
					System.out.println(((ShapedRecipes) o).recipeOutputItemID);
				}
			}

		}
		return recipesAdded;		
	}
	 */
}
